//
// Copyright (c) 2011 Alex Nesterenko
//

#ifndef NANE_OGLVERTEXBUFFERMANAGER_H
#   define  NANE_OGLVERTEXBUFFERMANAGER_H

#   include "nane/RenderSystem/IRenderSystem.h"
#   include "nane/RenderSystem/ogl/OGLAPI.h"

#   include <vector>

namespace nane
{
    class OGLBufferManager
    {
    public:
        OGLBufferManager();
        ~OGLBufferManager();

    public:
        IVertexBuffer* createVertexBuffer( EResourceUsage _usage, uint32 _verticesNum, uint32 _vertexSize
                                         , VertexElement* _elements, uint32 _elementsNum, byte* _initData );
        void releaseVertexBuffer( IVertexBuffer* _buffer );
        byte* lockVertexBuffer( IVertexBuffer* _vertexBuffer, uint32 _offset, uint32 _size );
        void unlockVertexBuffer( IVertexBuffer* _vertexBuffer );
        void setVertexBuffer( uint16 _streamNumber, IVertexBuffer* _vertexBuffer );
        IIndexBuffer* createIndexBuffer( EResourceUsage _usage, uint32 _indiciesNum, uint16* _initData );
        void releaseIndexBuffer( IIndexBuffer* _indexBuffer );
        uint16* lockIndexBuffer( IIndexBuffer* _indexBuffer, uint32 _offset, uint32 _size );
        void unlockIndexBuffer( IIndexBuffer* _indexBuffer );
        void setIndexBuffer( IIndexBuffer* _indexBuffer );
        void drawPrimitive( EPrimitiveType _type, uint32 _startVertex, uint32 _primitiveCount );
        void drawIndexedPrimitive( EPrimitiveType _type, uint32 _baseVertexIndex, uint32 _minIndex
                                     , uint32 _verticesNum, uint32 _startIndex, uint32 _primitiveCount );

    private:
        void setActiveVertexBuffer_( GLuint _bufferID );
        void setActiveIndexBuffer_( GLuint _bufferID );
        void applyVertexDeclaration_( const std::vector<VertexElement>& _vertexElements, uint32 _vertexSize );

    private:
        IVertexBuffer* m_currentVertexBuffer;
        IIndexBuffer* m_currentIndexBuffer;
        GLuint m_activeVertexBuffer;
        GLuint m_activeIndexBuffer;
    };
}

#endif	// NANE_OGLVERTEXBUFFERMANAGER_H
